package com.atguigu.config;

import com.atguigu.bean.Color;
import com.atguigu.bean.Person;
import com.atguigu.bean.Red;
import com.atguigu.condition.LinuxCondition;
import com.atguigu.condition.WindowsCondition;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.annotation.*;

import java.util.Date;

@Configuration
// 放在类上，对类中的组件进行统一控制，当满足条件时，才会在容器中注册这个配置类里面配置的组件
//@Conditional(value = {LinuxCondition.class})
@Conditional(value = {WindowsCondition.class})
@Import(value = {Color.class, Red.class, MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})
//@ImportResource
public class MainConfig2 {

    @Bean(value = "person")
    //@Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON) // 设置为单实例，容器启动就会调用方法创建所有的单实例对象
    //@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE) // 设置为多实例，容器启动不会调用方法创建对象,当使用到此多实例对象时，容器才会去创建实例对象，并且每获取一次，都会调用此方法生成一个新的实例对象
    @Lazy(value = true)
    public Person person() {
        System.out.println("向容器中添加person组件...");
        return new Person("张三", 25);
    }

    /*
     * @Conditional：按照一定条件给容器中添加组件
     */
    @Conditional(value = {WindowsCondition.class})
    @Bean(value = "bill")
    public Person person01() {
        return new Person("Bill Gates", 62);
    }

    @Conditional(value = {LinuxCondition.class})
    @Bean(value = "liuns")
    public Person person02() {
        return new Person("linus", 48);
    }

    @Bean
    public ColorFactoryBean colorFactoryBean(){
        return new ColorFactoryBean();
    }

    /**
     * 给容器中添加组件的几种方式：
     * 1. 包扫描+组件标注注解的方式：@ComponentScan + 注解(@Controller,@Service,@Repository,@Component),局限性在于只有我们自己写的类才能使用此种方式
     * 2. @Bean注解导入第三方包里面的组件：在配置类中，使用@Bean注解给容器添加组件，好处是可以导入第三方的组件到容器中
     * 3. @Import快速给容器中导入一个组件
     *      3.1、@Import(要导入到容器中的组件)，id默认是组件的全类名
     *      3.2、@Import(使用ImportSelector导入需要的组件的全类名数组)
     *      3.3、@Import(使用ImportBeanDefinitionRegister手动注册bean到容器中)
     * 4. 通过Spring提供的FactoryBean向容器中注入组件
     *      4.1、 默认获取到的是工厂bean调用getObject创建的对象
     *      4.2、 要获取工厂Bean本身，需要给id前面加一个&，如&colorFactoryBean
     */
}
